package top.wyloop.fasthome.logger;

import cn.dev33.satoken.exception.NotLoginException;
import cn.dev33.satoken.exception.NotPermissionException;
import cn.dev33.satoken.exception.NotRoleException;
import com.alibaba.fastjson2.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.MDC;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import top.wyloop.fasthome.result.RetResult;

/**
 * 注意此类只能处理Controller中使用了诸如@SaCheckLogin等注解的方法，
 * 使用了注解的方法通过校验时才会到ControllerLogAspect，否则被此类拦截异常并处理。
 * 对于方法中调用Sa-Token框架API时抛出的异常会先被ControllerLogAspect中的AroundAdvice拦截处理，
 * 所以ControllerLogAspect中的AroundAdvice也要处理NotLoginException、NotRoleException、NotPermissionException异常
 *
 * @author Wyatt6
 * @date 2025/5/12
 */
@Slf4j
@ControllerAdvice
public class SatokenExceptionHandler {
    @ExceptionHandler(NotLoginException.class)
    @ResponseBody
    public RetResult notLoginExceptionHandler(Exception e) {
        log.info("Sa-Token验证异常：未登录");
        RetResult result = new RetResult();
        result.fail().addData("code", 401).setMessage("未登录").setTraceId(MDC.get("traceId"));
        log.info("响应: {}", JSONObject.toJSONString(result));
        return result;
    }

    @ExceptionHandler(NotRoleException.class)
    @ResponseBody
    public RetResult notRoleExceptionHandler(Exception e) {
        log.info("Sa-Token验证异常：角色异常");
        RetResult result = new RetResult();
        result.fail().addData("code", 403).setMessage("用户权限不足").setTraceId(MDC.get("traceId"));
        log.info("响应: {}", JSONObject.toJSONString(result));
        return result;
    }

    @ExceptionHandler(NotPermissionException.class)
    @ResponseBody
    public RetResult notPermissionExceptionHandler(Exception e) {
        log.info("Sa-Token验证异常：权限异常");
        RetResult result = new RetResult();
        result.fail().addData("code", 403).setMessage("用户权限不足").setTraceId(MDC.get("traceId"));
        log.info("响应: {}", JSONObject.toJSONString(result));
        return result;
    }
}
